package main

import (
	"fmt"
	"reflect"
	"unsafe"
)

var XName string

type User struct {
	Name string `tag:"name1"`
	code int    `tag:"code1"`
}

// -tags  ==> // +build <tag>
//go:generate go build -ldflags "-s -w -X main.XName=jmz" -tags "dev release" .
//go:generate go build -ldflags "-s -w -X main.XName=jmz" .
func main() {
	fmt.Println(XName)
	hello()

	p := new(User)
	//t := reflect.TypeOf(p).Elem()
	v := reflect.ValueOf(p).Elem()
	name := v.FieldByName("Name")
	code := v.FieldByName("code")

	fmt.Printf("name: canaddr = %v, canset=%v\n", name.CanAddr(), name.CanSet())
	fmt.Printf("code: canaddr = %v, canset=%v\n", code.CanAddr(), code.CanSet())

	if name.CanSet() {
		name.SetString("jmz")
	}

	if code.CanAddr() {
		*(*int)(unsafe.Pointer(code.UnsafeAddr())) = 100
	}

	fmt.Printf("%+v\n", *p)

	Test()
}

func Test() {
	p := new(User)
	t := reflect.TypeOf(p).Elem()
	for i := 0; i < t.NumField(); i++ {
		fmt.Println(t.Field(i).Name, t.Field(i).Type, t.Field(i).Tag.Get("tag"), t.Field(i).Offset)
	}

}
